﻿namespace Tszy.Unlimited.Base.Infrastructure.Caching;

/// <summary>
/// 缓存管理器
/// </summary>
public interface ICacheManager
{
    /// <summary>
    /// 获得所有 Key。
    /// </summary>
    IEnumerable<string> Keys { get; }

    /// <summary>
    /// 增加缓存值。
    /// </summary>
    /// <typeparam name="TValue">类型。</typeparam>
    /// <param name="key">键对象。</param>
    /// <param name="value">值对象。</param>
    /// <returns>是否成功，成功返回 False，否则返回 True。</returns>
    bool Add<TValue>(string key, TValue value);

    /// <summary>
    /// 获取缓存值。
    /// </summary>
    /// <typeparam name="TValue">值类型。</typeparam>
    /// <param name="key">键对象。</param>
    /// <returns>值对象。</returns>
    TValue? Get<TValue>(string key);

    /// <summary>
    /// 获取缓存值，如果不存在，则添加缓存。
    /// </summary>
    /// <typeparam name="TValue">值类型。</typeparam>
    /// <param name="key">键对象。</param>
    /// <param name="acquire">获得值对象的委托。</param>
    /// <returns>值对象。</returns>
    TValue GetOrAdd<TValue>(string key, Func<TValue> acquire);

    /// <summary>
    /// 获取缓存值，如果不存在，则添加缓存。
    /// </summary>
    /// <typeparam name="TValue">值类型。</typeparam>
    /// <param name="key">键对象。</param>
    /// <param name="acquire">获得值对象的委托。</param>
    /// <param name="validFor">过期时长。</param>
    /// <returns>值对象。</returns>
    TValue GetOrAdd<TValue>(string key, Func<TValue> acquire, TimeSpan validFor);

    /// <summary>
    /// 设置缓存值。
    /// </summary>
    /// <typeparam name="TValue">值类型。</typeparam>
    /// <param name="key">键对象。</param>
    /// <param name="value">值对象。</param>
    void Set<TValue>(string key, TValue value);

    /// <summary>
    /// 设置缓存值。
    /// </summary>
    /// <typeparam name="TValue">值类型。</typeparam>
    /// <param name="key">键对象。</param>
    /// <param name="value">值对象。</param>
    /// <param name="timeOut">有效时长。</param>
    void Set<TValue>(string key, TValue value, TimeSpan timeOut);

    /// <summary>
    /// 使用并发锁设置缓存值。
    /// </summary>
    /// <typeparam name="TValue">值类型。</typeparam>
    /// <param name="key">键对象。</param>
    /// <param name="action">缓存值修改方法。</param>
    /// <param name="timeOut">缓存的有效时长。</param>
    /// <param name="lockTimeOut">锁的有效时长。</param>
    void SetLock<TValue>(string key, Func<TValue, TValue> action, TimeSpan timeOut, TimeSpan lockTimeOut);

    /// <summary>
    /// 为给定 key 设置过期时间。
    /// </summary>
    /// <param name="key">键对象。</param>
    /// <param name="timeOut">有效时长。</param>
    /// <returns></returns>
    bool Expire(string key, TimeSpan timeOut);

    /// <summary>
    /// 为给定 key 设置过期时间。
    /// </summary>
    /// <param name="key">键对象。</param>
    /// <param name="timeOut">过期时间。</param>
    /// <returns></returns>
    bool ExpireAt(string key, DateTime timeOut);

    /// <summary>
    /// 移除缓存值。
    /// </summary>
    /// <param name="key">键对象。</param>
    bool Remove(string key);

    /// <summary>
    /// 移除缓存值。
    /// </summary>
    /// <typeparam name="TValue">值类型</typeparam>
    /// <param name="key">键对象。</param>
    /// <param name="result">值对象。</param>
    /// <returns>移除是否成功。</returns>
    bool Remove<TValue>(string key, out TValue? result);

    /// <summary>
    /// 清空缓存。
    /// </summary>
    void Clear();

    #region 数值操作

    /// <summary>
    /// 根据指定的Key，将值加1(仅整型有效)。
    /// </summary>
    /// <param name="key">键对象。</param>
    void IncrementValue(string key);

    /// <summary>
    /// 根据指定的Key，将值加上指定值(仅整型有效)。
    /// </summary>
    /// <param name="key">键对象。</param>
    /// <param name="value">值对象。</param>
    void IncrementValueBy(string key, int value);

    /// <summary>
    /// 根据指定的Key，将值减1(仅整型有效)。
    /// </summary>
    /// <param name="key">键对象。</param>
    void DecrementValue(string key);

    /// <summary>
    /// 根据指定的Key，将值减去指定值(仅整型有效)。
    /// </summary>
    /// <param name="key">键对象。</param>
    /// <param name="value">值对象。</param>
    void DecrementValueBy(string key, int value);

    #endregion 数值操作

    #region 集合操作

    /// <summary>
    /// 添加一个项到内部的List。
    /// </summary>
    /// <param name="listId">键对象。</param>
    /// <param name="value">值对象。</param>
    void AddItemToList(string listId, string value);

    /// <summary>
    /// 一次过将参数中的List中的多个值添加入内部的List。
    /// </summary>
    /// <param name="listId">键对象。</param>
    /// <param name="value">值对象。</param>
    void AddRangeToList(string listId, IEnumerable<string> value);

    /// <summary>
    /// 移除指定ListId的内部List中第二个参数值相等的那一项。
    /// </summary>
    /// <param name="listId">键对象。</param>
    /// <param name="value">值对象。</param>
    void RemoveItemFromList(string listId, string value);

    /// <summary>
    /// 获取指定ListId的内部List的所有值。
    /// </summary>
    /// <param name="listId">键对象。</param>
    /// <returns>值对象。</returns>
    IEnumerable<string> GetAllItemsFromList(string listId);

    #endregion 集合操作
}
